'''
Created on 21/09/2009

@author: b1u3fox
'''
from logica.proposiciones import *

class TablaVerdad(object):
    
    def _igualar_columnas(self):
        for proposicion, valores in self.valores_verdad.iteritems():
            if self.cant_filas > len(valores):
                factor = int(self.cant_filas / len(valores))
                self.valores_verdad[proposicion] = valores * factor
    
    def _generar_valores_verdad(self, proposicion):
        if ((isinstance(proposicion, Enunciado) or 
            isinstance(proposicion, ProposicionPredicativa)) and 
            proposicion not in self.proposiciones):
            self.proposiciones.append(str(proposicion))
            self.cant_prop_atom += 1
            self.cant_filas = 2**self.cant_prop_atom
            mitad = int(self.cant_filas / 2)
            self.valores_verdad[str(proposicion)] = [True] * mitad
            self.valores_verdad[str(proposicion)] += [False] * mitad
        elif str(proposicion) not in self.proposiciones:
            if isinstance(proposicion, ProposicionMolecular):
                self._generar_valores_verdad(proposicion.proposicion1)
                if not isinstance(proposicion, Negacion):
                    self._generar_valores_verdad(proposicion.proposicion2)
                    valores2 = self.valores_verdad[str
                                                   (proposicion.proposicion2)]
                valores1 = self.valores_verdad[str(proposicion.proposicion1)]
                self.proposiciones.append(str(proposicion))
                self.valores_verdad[str(proposicion)] = []
                i = 0
                while i < self.cant_filas:
                    if isinstance(proposicion, Negacion):
                        valor = not valores1[i]
                    elif isinstance(proposicion, Disyuncion):
                        valor = valores1[i] or valores2[i]
                    elif isinstance(proposicion, Conjuncion):
                        valor = valores1[i] and valores2[i]
                    elif isinstance(proposicion, Implicacion):
                        valor = (not valores1[i]) or valores2[i]
                    elif isinstance(proposicion, DobleImplicacion):
                        valor = (((not valores1[i]) or valores2[i]) and 
                                 (valores1[i] or (not valores2[i])))
                    self.valores_verdad[str(proposicion)].append(valor)
                    i += 1
        self._igualar_columnas()
                    
    def _generar_filas(self):
        i = 0
        while i < self.cant_filas:
            fila = []
            j = 0
            while j < len(self.proposiciones):
                proposicion = self.proposiciones[j]
                valores = self.valores_verdad[proposicion]
                fila.append(valores[i])
                j += 1
            self.filas.append(fila)
            i += 1
    
    def __init__(self, proposicion):
        self.filas = []
        self.cant_filas = 0
        self.cant_prop_atom = 0
        self.proposiciones = []
        self.valores_verdad = {}
        self._generar_valores_verdad(proposicion)
        self.proposiciones.sort(lambda x,y: cmp(len(str(x)), len(str(y))))
        self._generar_filas()
        
    def __repr__(self):
        proposiciones = [str(prop) for prop in self.proposiciones]
        filas = [str(fila) for fila in self.filas]
        tabla = [str(proposiciones)] + filas
        return '\n'.join(tabla)